package config

import (
	"context"
	"log"
	"sync/atomic"
	"unsafe"

	ttcc "code.byted.org/bytertc/common_utils/tcc"
)

const keyRecordEnabledAppList = `record_app`
const keyTosConfig = `tos_config`
const defaultApp = `default`

//go:generate mockgen -destination ../mock/config/tcc.go . DynamicConfig

type DynamicConfig interface {
	IsRecordEnabled(ctx context.Context, appId string) bool
	GetTOSConfig(ctx context.Context, appId string) (bucket string, ak string)
}

func NewDynamicConfig() DynamicConfig {
	return &tcc{}
}

type tcc struct{}

func (t *tcc) IsRecordEnabled(ctx context.Context, appId string) bool {
	for _, value := range Settings().RecordApp {
		if appId == value {
			return true
		}
	}
	return false
}

func (t *tcc) GetTOSConfig(ctx context.Context, appId string) (bucket string, ak string) {

	tos, ok := Settings().TosConfig[appId]
	if ok {
		return tos.Bucket, tos.AK
	}
	tos = Settings().TosConfig[defaultApp]
	return tos.Bucket, tos.AK
}

type Configuration struct {
	RecordApp           []string                    `key:"record_app" default:"[]"`
	TosConfig           map[string]TosConfig        `key:"tos_config" default:"{}"`
	StorageRegionConfig StorageRegionConfig         `key:"storage_region_config" default:"{}"`
	DefaultRecordHost   string                      `key:"default_record_host" default:""`
	RateLimiterConfig   map[string]map[string]int64 `key:"rate_limiter_config" default:"{}"`
}

func (c *Configuration) Copy() ttcc.Configer {
	return &Configuration{}
}

var c ttcc.Configer = &Configuration{}
var dconf = unsafe.Pointer(&c)
var config *unsafe.Pointer = &dconf

// Settings is used to reload Configuration
func Settings() *Configuration {
	return (*(*ttcc.Configer)(atomic.LoadPointer(config))).(*Configuration)
}

func MustInitTcc(serviceName string) {
	var err error
	config, err = ttcc.Init(context.Background(), serviceName, &Configuration{}, true)
	if err != nil {
		panic(err)
	}
	log.Printf("tcc init result is %+v\n", Settings())
}

type StorageRegionConfig struct {
	Tos         RegionMap            `json:"Tos"`         // Volc Engine Tos
	Vod         RegionMap            `json:"Vod"`         // Volc Engine Vod
	BytePlusVod RegionMap            `json:"BytePlusVod"` // Byte Plus Vod
	VendorIDs   map[uint32]string    `json:"VendorIDs"`   // key = Vendor value=VendorID
	Custom      map[string]RegionMap `json:"Custom"`      // key = VendorID
}

type RegionMap struct {
	EndPointFormat string            `json:"EndPointFormat"`
	BoeTosEndPoint string            `json:"BoeTosEndPoint"`
	RegionIDs      map[uint32]string `json:"RegionIDs"`
}

type TosConfig struct {
	Bucket string `json:"bucket" default:""`
	AK     string `json:"access_key" default:""`
}
